from xpinyin import Pinyin
from dateutil import parser
from pyppeteer.launcher import connect
from pyppeteer.page import Page
from pyppeteer.browser import Browser
from urllib.parse import urlparse, parse_qs
from pyppeteer.element_handle import ElementHandle
from lxml import etree
from config import *
import requests,subprocess,asyncio,os,re,json
import random,base64,time,datetime,string

async def openChrome(dlip=None):
    flag=False
    try:
        session=requests.session()
        res=session.get('http://localhost:9222/json/version')
        if res.status_code==200 and res.json():
            flag=True
    except Exception as e:
        print('未启动浏览器等待启动')

    try:
        if not flag:
            exepath=find_chrome_path()
            print(exepath)
            if not exepath:
                return None
            dlstr='' if not dlip else f' --proxy-server=http://{dlip}'
            subprocess.Popen(f'"{exepath}" --remote-debugging-port=9222{dlstr}',shell=True, stdin=subprocess.PIPE,
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        res=session.get('http://localhost:9222/json/version')
        bobj=res.json()
        browser=await connect({
            'browserWSEndpoint':bobj['webSocketDebuggerUrl'],
            'args':['--disable-infobars','--start-maximized'
                    ],    
            'defaultViewport':None
        })
        
        return browser

    except Exception as e:
        print(e)

async def openSunBrowser(user_id):

    params={
        'k':ADSPower_API_KEY,
        'open_tabs':1,
        'ip_tab':0,
        'user_id':user_id
    }


    while True:    
        res = requests.get(f'{ADSPower_API_URL}/api/v1/browser/start',params=params)
        res_data = res.json()
        if res_data['code']==0:
            break
        if res_data['code'] != 0:

            if res_data['code']==-1 and res_data['msg']=='Too many request per second, please check':
                time.sleep(5)
            else:
                print("启动指纹浏览器错误:", res_data)
                return
        time.sleep(3)
    
    ws_url = res_data['data']['ws']['puppeteer']
    browser=await connect({
            'browserWSEndpoint':ws_url,
            'args':['--disable-infobars','--start-maximized'
                    ],
            'defaultViewport':None
    })
    print(f'成功启动浏览器,环境id:{user_id}')
    return browser


async def wait_one_xpath(page:Page,xpath,max_wait=None) -> ElementHandle:

    wait_count=0
    while True:
        try:
            ss=await page.xpath(xpath)
            if ss:
                print(f'等待{xpath} 成功')
                return ss[0]
            print(f'等待{xpath}')
        except Exception as e:
            #print(f'等待xpath{xpath}错误:{jj+1}次 =>{e}')
            pass
        await asyncio.sleep(1)
        wait_count+=1
        if max_wait and wait_count>max_wait:
            return

def find_chrome_path():
    possible_paths = [
        r'C:\Program Files\Google\Chrome\Application\chrome.exe',  # 默认安装路径
        r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe',  # 32位版本的默认安装路径
    ]

    for path in possible_paths:
        if os.path.exists(path):
            return path

    try:
        from winreg import ConnectRegistry, OpenKey, HKEY_LOCAL_MACHINE, QueryValue
        reg_path = r'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe'
        with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as hkey:
            with OpenKey(hkey, reg_path) as key:
                return QueryValue(key, None)
    except:
        pass

    return None

def convert_to_timestamp(time_str):
    # 使用 dateutil.parser 解析时间字符串
    try:
        dt = parser.parse(time_str)
        
        # 转换为时间戳
        timestamp = time.mktime(dt.timetuple())

        return int(timestamp)
    except Exception as e:
        return -1

def timestamp_to_string(timestamp, format='%Y-%m-%d %H:%M:%S'):
    """
    将时间戳转换为时间字符串

    参数:
    - timestamp (int or float): 时间戳
    - format (str): 时间字符串格式，默认为 '%Y-%m-%d %H:%M:%S'

    返回:
    - str: 格式化的时间字符串
    """
    dt = datetime.datetime.fromtimestamp(timestamp)
    return dt.strftime(format)

async def repeat_goto(page:Page,url:str,errcount=3):
    pp=0
    while True:
        try:
            await page.goto(url)
            break
        except Exception as e:
            print(f'浏览器goto错误 => {e}')
            pp+=1
        if pp>=3:
            return '代理错误'

async def repeat_reload(page:Page):

    while True:
        try:
            await page.reload()
            break
        except Exception as e:
            print(f'浏览器goto错误 => {e}')

def get_random_code(length=8):
    characters = string.ascii_letters + string.digits
    random_code = ''.join(random.choice(characters) for _ in range(length))
    return random_code

def get_url_param(url, param_name):
    # 使用 urlparse 解析 URL
    parsed_url = urlparse(url)
    
    # 使用 parse_qs 将查询参数解析为字典
    query_params = parse_qs(parsed_url.query)
    
    # 如果参数存在，返回其值（列表形式），否则返回 None
    return query_params.get(param_name, [None])[0]

def getpy(mes):
    p=Pinyin()
    return p.get_pinyin(mes,splitter='',convert='capitalize')

def kchrome():
    import psutil
    pids = psutil.pids()
    for pid in pids:
        try:
            p = psutil.Process(pid)
            # print('pid-%s,pname-%s' % (pid, p.name()))
            if p.name() == 'chrome.exe':
                #print(f'关闭{pid} => {p.name()}')
                cmd = 'taskkill /F /IM chrome.exe'
                os.system(cmd)

        except Exception as e:
            pass

async def get_cookie_string(url):
    try:
        browser =await openChrome()
        if not browser:
            print('未找到chrome路径')
            return
        page = await browser.newPage()
        await page.goto(url,options={'timeout':0})
        await asyncio.sleep(3)
        cookies = await page.cookies()
        cookie_str = "; ".join([f"{cookie['name']}={cookie['value']}" for cookie in cookies])
        await page.close()
        print('获取cookie成功')
        return cookie_str
    except Exception as e:
        print(e)
        await page.close()
        return None
    
def check_amazon_yzm(session,cot,dl=None):
    headers={
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }
    cur_ck=None
    while True:
        html=etree.HTML(cot)
        imgls=html.xpath('//div[@class="a-box-inner"]//img/@src')
        
        if not imgls:
            print(f'非验证码页面')
            return cot,cur_ck
        imgUrl=imgls[0]
        amzn=html.xpath('//form//input[@name="amzn"]/@value')
        amznr=html.xpath('//form//input[@name="amzn-r"]/@value')
        #print(amzn,amznr)
        res_img=session.get(imgUrl,headers=headers,timeout=30)
        cot_img=res_img.content
        lsf=base64.b64encode(cot_img)
        resyzm=session.request('post','http://127.0.0.1:1688/VerificationCode.php',data=lsf,timeout=30)
        captchacode=(resyzm.text).strip()
        print(f'解析出验证码为{captchacode}')
        params={
            'amzn':amzn[0],
            'amzn-r':amznr[0],
            'field-keywords':captchacode
        }
        proxies, ck = dl
        res=session.get(f'http://amazon.com/errors/validateCaptcha',params=params,headers=headers, proxies=proxies,timeout=30)
        code = res.status_code
        cot=res.text

        print(f'验证码解析后,内容长度:{len(cot)},状态码:{code}')
        if not imgls and len(cot)>20000:
            ck=res.cookies
            return cot,ck
        

async def check_amazon_pgyzm(page:Page):
    count=0
    while True:
        try:
            if count>=5:
                await page.reload()
            el_deliver=await page.xpath('//div[@id="glow-ingress-block"]')
            if el_deliver:
                print('验证成功')
                return
            
            cot=await page.content()
            html=etree.HTML(cot)
            imgls=html.xpath('//div[@class="a-box-inner"]//img/@src')
            if imgls:
                print('出现验证码...')
                imgUrl=imgls[0]
                print(f'图片地址:{imgUrl}')
                res_img=requests.get(imgUrl)
                cot_img=res_img.content
                lsf=base64.b64encode(cot_img)
                resyzm=requests.request('post','http://127.0.0.1:1688/VerificationCode.php',data=lsf)
                captchacode=(resyzm.text).strip()
                print(f'解析出验证码为{captchacode}')

                await page.type('#captchacharacters',captchacode,{'delay':100})
                await asyncio.sleep(1)
                await page.click('button.a-button-text')
                await asyncio.sleep(3)

        except Exception as e:
            print(e)
        
        count+=1

async def get_amazon_ck(bid=None) -> str:
    if bid is None:
        browser=await openChrome()
    else:
        browser=await openSunBrowser(bid)
    page = await browser.newPage()
    aaa=await repeat_goto(page,'https://www.amazon.com')
    if aaa=='代理错误':
        await browser.close()
        return aaa
    await check_amazon_pgyzm(page)
    await wait_one_xpath(page,'//div[@id="glow-ingress-block"]')

    cot =await page.content()
    
    deliver=etree.HTML(cot).xpath('//span[@id="glow-ingress-line2"]/text()')

    deliver_str=deliver[0].strip().lower()

    if '10024' not in deliver_str:
        await wait_one_xpath(page,'//*[@id="nav-global-location-popover-link"]')
        while True:
            try:
                adel=await page.xpath('//*[@id="GLUXChangePostalCodeLink"]')
                if adel:
                    break
                await page.click('#nav-global-location-popover-link')

            except Exception as e:
                pass
            await asyncio.sleep(2)

        ppp=await page.xpath('//a[@class="a-link-normal a-declarative" and @id="GLUXChangePostalCodeLink"]')

        if not ppp:
            await page.click('#GLUXChangePostalCodeLink',{'delay':1500})
            await wait_one_xpath(page,'//input[@id="GLUXZipUpdateInput"]')
            await asyncio.sleep(5)
        # 清空输入框
        await page.evaluate('''() => {
            document.getElementById('GLUXZipUpdateInput').value = ''
        }''')

        await page.type('#GLUXZipUpdateInput','10024',{'delay':100})
        await asyncio.sleep(1)
        while True:
            try:
                await page.click('#GLUXZipUpdate-announce')
                break
            except Exception as e:
                pass
            await asyncio.sleep(2)
           
        await asyncio.sleep(5)
        await repeat_reload(page)

    cookies = await page.cookies()
    cookie_str = "; ".join([f"{cookie['name']}={cookie['value']}" for cookie in cookies])
    await browser.close()
    return cookie_str

def get_browser_environment(group_id=Group_ID):

    url=f'{ADSPower_API_URL}/api/v1/user/list'
    params={
        'group_id':group_id,
        'page_size':100
    }
    bids=[]
    res=requests.get(url,params)
    try:
        json_data=res.json()
        bids=[bitem['user_id'] for bitem in json_data['data']['list']]
        return bids
    except Exception as e:
        print(e)
    

def create_browser_environment(name,dlitem,proxy_type='socks5'):

    dlip,port,uid,pwd=dlitem
    url=f'{ADSPower_API_URL}/api/v1/user/create'
    user_proxy_config = {
        "proxy_type": proxy_type,
        "proxy_host": dlip,
        "proxy_port": port,
        "proxy_user": uid,
        "proxy_password": pwd,
        "proxy_soft": "other"
    }

    # 构建 payload
    payload = {
        "name": name,
        "user_proxy_config": user_proxy_config,
        "domain_name": "www.amazon.com",
        "ip":dlip,
        "group_id":Group_ID,
        "fingerprint_config": {
            "language": ["en-US","en","zh-CN","zh"]
        }
        
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()  # Raise an error for bad status codes
        return response.json()
    except requests.exceptions.RequestException as e:
        return {"code": -1, "data": {}, "msg": str(e)}

def create_browser_environment_no_proxy(name):

    url=f'{ADSPower_API_URL}/api/v1/user/create'
    user_proxy_config = {
        "proxy_soft": "no_proxy"
    }

    # 构建 payload
    payload = {
        "name": name,
        "user_proxy_config": user_proxy_config,
        "domain_name": "www.amazon.com",
        "group_id":Group_ID,
        "fingerprint_config": {
            "language": ["en-US","en","zh-CN","zh"]
        }
        
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()  # Raise an error for bad status codes
        return response.json()['data']['id']
    except requests.exceptions.RequestException as e:
        return {"code": -1, "data": {}, "msg": str(e)}

def del_browser_environment(bid):
    url=f'{ADSPower_API_URL}/api/v1/user/delete'
    payload = {
        'user_ids':[bid]
    }

    try:
        response = requests.post(url, json=payload)
        response.raise_for_status()  # Raise an error for bad status codes
        return response.json()
    except requests.exceptions.RequestException as e:
        return {"code": -1, "data": {}, "msg": str(e)}

